package org.dromara.system.service.impl;

import org.dromara.common.core.domain.R;
import org.dromara.common.core.utils.DateUtils;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.system.domain.PayGroupAccount;
import org.dromara.system.domain.PayGroupType;
import org.dromara.system.domain.SysUser;
import org.dromara.system.mapper.*;
import org.springframework.stereotype.Service;
import org.dromara.system.domain.bo.PayGroupBo;
import org.dromara.system.domain.vo.PayGroupVo;
import org.dromara.system.domain.PayGroup;
import org.dromara.system.service.IPayGroupService;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 轮询组Service业务层处理
 *
 * @author Gavino
 * @date 2024-10-31
 */
@RequiredArgsConstructor
@Service
public class PayGroupServiceImpl implements IPayGroupService {

    private final PayGroupMapper baseMapper;
    private final SysUserMapper userMapper;
    private final PayGroupAccountMapper groupAccountMapper;
    private final PayAccountMapper accountMapper;
    private final PayGroupTypeMapper groupTypeMapper;

    @Transactional
    @Override
    public R<?> copy(Long groupId, String groupName) {

        PayGroup group = baseMapper.selectById(groupId);
        if (group == null) {
            return R.fail("轮询组不存在");
        }

        List<PayGroupType> groupTypes = groupTypeMapper.selectList(new LambdaQueryWrapper<PayGroupType>().eq(PayGroupType::getGroupId, groupId));
        if (groupTypes.isEmpty()) {
            return R.fail("该轮询组未配置支付平台数据");
        }

        group.setGroupName(groupName);
        group.setGroupId(null);
        group.setUpdateId(null);
        group.setUpdateName(null);
        group.setUpdateTime(null);
        baseMapper.insert(group);

        List<PayGroupAccount> groupAccounts = groupAccountMapper.selectList(new LambdaQueryWrapper<PayGroupAccount>().eq(PayGroupAccount::getGroupId, groupId));
        Map<Long, List<PayGroupAccount>> accountMap = groupAccounts.stream().collect(Collectors.groupingBy(PayGroupAccount::getGroupTypeId));

        List<PayGroupAccount> inserts = new ArrayList<>();

        groupTypes.forEach(type -> {
            List<PayGroupAccount> tmpList = accountMap.get(type.getId());

            type.setId(null);
            type.setGroupId(group.getGroupId());
            type.setCreateTime(DateUtils.getNowDate());
            type.setUpdateTime(null);
            groupTypeMapper.insert(type);

            if (tmpList != null) {
                tmpList.forEach(account -> {
                    account.setId(null);
                    account.setGroupId(group.getGroupId());
                    account.setGroupTypeId(type.getId());
                    account.setCreateTime(DateUtils.getNowDate());
                    account.setUpdateId(null);
                    account.setUpdateName(null);
                    account.setUpdateTime(null);
                    inserts.add(account);
                });
            }
        });

        if (!inserts.isEmpty()) {
            groupAccountMapper.insertBatch(inserts);
        }

        return R.ok("复制成功");
    }

    /**
     * 查询轮询组
     *
     * @param groupId 主键
     * @return 轮询组
     */
    @Override
    public PayGroupVo queryById(Long groupId) {
        return baseMapper.selectVoById(groupId);
    }

    /**
     * 分页查询轮询组列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 轮询组分页列表
     */
    @Override
    public TableDataInfo<PayGroupVo> queryPageList(PayGroupBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<PayGroup> lqw = buildQueryWrapper(bo);
        Page<PayGroupVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询符合条件的轮询组列表
     *
     * @param bo 查询条件
     * @return 轮询组列表
     */
    @Override
    public List<PayGroupVo> queryList(PayGroupBo bo) {
        LambdaQueryWrapper<PayGroup> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<PayGroup> buildQueryWrapper(PayGroupBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<PayGroup> lqw = Wrappers.lambdaQuery();
        if (LoginHelper.isAgent()) {
            lqw.eq(PayGroup::getAgentId, LoginHelper.getUserId());
        }
        else if (LoginHelper.isManager()) {
           String groupIds = userMapper.selectById(LoginHelper.getUserId()).getGroupIds();
           if(StringUtils.isNotEmpty(groupIds)) {
               lqw.in(PayGroup::getGroupId, Arrays.stream(groupIds.split(",")).map(Long::valueOf).toList());
           } else {
               lqw.eq(PayGroup::getGroupId, 0);
           }
        }
        else if (!LoginHelper.isSuperAdmin()) {
            lqw.eq(PayGroup::getAgentId, LoginHelper.getLoginUser().getAgentId());
        }

        if (LoginHelper.isSupplier()) {
            List<Long> groupIds = accountMapper.selectGroupIdBySupplierId(LoginHelper.getUserId());
            if (groupIds.isEmpty()) {
                lqw.eq(PayGroup::getGroupId, 0);
            } else {
                lqw.in(PayGroup::getGroupId, groupIds);
            }
        }

        lqw.like(StringUtils.isNotBlank(bo.getGroupName()), PayGroup::getGroupName, bo.getGroupName());
        return lqw;
    }

    /**
     * 新增轮询组
     *
     * @param bo 轮询组
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByBo(PayGroupBo bo) {
        PayGroup add = MapstructUtils.convert(bo, PayGroup.class);
        add.setAgentId(LoginHelper.getUserId());
        add.setAgentName(LoginHelper.getUsername());
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setGroupId(add.getGroupId());
        }
        return flag;
    }

    /**
     * 修改轮询组
     *
     * @param bo 轮询组
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(PayGroupBo bo) {
        PayGroup update = MapstructUtils.convert(bo, PayGroup.class);
        update.setUpdateId(LoginHelper.getUserId());
        update.setUpdateName(LoginHelper.getUsername());
        update.setUpdateTime(DateUtils.getNowDate());
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 校验并批量删除轮询组信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        LambdaQueryWrapper<PayGroup> query = new LambdaQueryWrapper<>();
        query.in(PayGroup::getGroupId, ids);
        if (LoginHelper.isAgent()) {
            query.eq(PayGroup::getAgentId, LoginHelper.getUserId());
        }
        return baseMapper.delete(query) > 0;
    }
}
